package com.example.backend.controller;

import com.example.backend.dto.ApiResponse;
import com.example.backend.dto.PageResponse;
import com.example.backend.dto.TicketStatusTrackingDto;
import com.example.backend.domain.enums.TicketStatusTrackingType;
import com.example.backend.constants.RoleConstants;
import com.example.backend.security.RequirePermission;
import com.example.backend.service.TicketStatusTrackingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.Instant;
import java.util.List;

/**
 * 工单状态跟踪控制器
 */
@RestController
@RequestMapping("/api/tickets")
@Tag(name = "工单状态跟踪", description = "工单状态跟踪和操作历史管理接口")
@SecurityRequirement(name = "Bearer Authentication")
public class TicketStatusTrackingController {
    
    @Autowired
    private TicketStatusTrackingService trackingService;
    
    /**
     * 获取工单的状态跟踪历史
     */
    @GetMapping("/{ticketId}/tracking")
    @Operation(summary = "获取工单状态跟踪历史", description = "获取指定工单的所有状态跟踪记录")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<List<TicketStatusTrackingDto>>> getTicketTrackingHistory(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            List<TicketStatusTrackingDto> trackingHistory = trackingService.getTicketTrackingHistory(ticketId);
            return ResponseEntity.ok(ApiResponse.success("获取状态跟踪历史成功", trackingHistory));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取状态跟踪历史失败: " + e.getMessage()));
        }
    }
    
    /**
     * 分页获取工单的状态跟踪历史
     */
    @GetMapping("/{ticketId}/tracking/page")
    @Operation(summary = "分页获取工单状态跟踪历史", description = "分页获取指定工单的状态跟踪记录")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<PageResponse<TicketStatusTrackingDto>>> getTicketTrackingHistoryPage(
            @Parameter(description = "工单ID") @PathVariable Long ticketId,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int size,
            @Parameter(description = "排序字段") @RequestParam(defaultValue = "createdAt") String sortBy,
            @Parameter(description = "排序方向") @RequestParam(defaultValue = "desc") String sortDir) {
        try {
            Sort sort = Sort.by(Sort.Direction.fromString(sortDir), sortBy);
            Pageable pageable = PageRequest.of(page, size, sort);
            
            Page<TicketStatusTrackingDto> trackingPage = trackingService.getTicketTrackingHistory(ticketId, pageable);
            PageResponse<TicketStatusTrackingDto> pageResponse = PageResponse.of(trackingPage);
            
            return ResponseEntity.ok(ApiResponse.success("获取状态跟踪历史成功", pageResponse));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取状态跟踪历史失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取工单的状态变更历史
     */
    @GetMapping("/{ticketId}/tracking/status-changes")
    @Operation(summary = "获取工单状态变更历史", description = "获取指定工单的状态变更记录")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<List<TicketStatusTrackingDto>>> getStatusChangeHistory(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            List<TicketStatusTrackingDto> statusChanges = trackingService.getStatusChangeHistory(ticketId);
            return ResponseEntity.ok(ApiResponse.success("获取状态变更历史成功", statusChanges));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取状态变更历史失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取工单的分配历史
     */
    @GetMapping("/{ticketId}/tracking/assignments")
    @Operation(summary = "获取工单分配历史", description = "获取指定工单的分配变更记录")
    @RequirePermission(roles = {RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<List<TicketStatusTrackingDto>>> getAssignmentHistory(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            List<TicketStatusTrackingDto> assignments = trackingService.getAssignmentHistory(ticketId);
            return ResponseEntity.ok(ApiResponse.success("获取分配历史成功", assignments));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取分配历史失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取用户可见的跟踪记录
     */
    @GetMapping("/{ticketId}/tracking/visible")
    @Operation(summary = "获取用户可见的跟踪记录", description = "获取客户可见的工单跟踪记录")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<List<TicketStatusTrackingDto>>> getVisibleTrackingHistory(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            List<TicketStatusTrackingDto> visibleTracking = trackingService.getVisibleTrackingHistory(ticketId);
            return ResponseEntity.ok(ApiResponse.success("获取可见跟踪记录成功", visibleTracking));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取可见跟踪记录失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取工单的最后一次操作
     */
    @GetMapping("/{ticketId}/tracking/last-operation")
    @Operation(summary = "获取工单最后一次操作", description = "获取指定工单的最后一次操作记录")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<TicketStatusTrackingDto>> getLastOperation(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            return trackingService.getLastOperation(ticketId)
                    .map(tracking -> ResponseEntity.ok(ApiResponse.success("获取最后一次操作成功", tracking)))
                    .orElse(ResponseEntity.ok(ApiResponse.success("暂无操作记录", null)));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取最后一次操作失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取工单的最后一次状态变更
     */
    @GetMapping("/{ticketId}/tracking/last-status-change")
    @Operation(summary = "获取工单最后一次状态变更", description = "获取指定工单的最后一次状态变更记录")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<TicketStatusTrackingDto>> getLastStatusChange(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            return trackingService.getLastStatusChange(ticketId)
                    .map(tracking -> ResponseEntity.ok(ApiResponse.success("获取最后一次状态变更成功", tracking)))
                    .orElse(ResponseEntity.ok(ApiResponse.success("暂无状态变更记录", null)));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取最后一次状态变更失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取操作人的操作记录
     */
    @GetMapping("/tracking/operator/{operatorId}")
    @Operation(summary = "获取操作人记录", description = "获取指定操作人的所有操作记录")
    @RequirePermission(roles = {RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<PageResponse<TicketStatusTrackingDto>>> getOperatorHistory(
            @Parameter(description = "操作人ID") @PathVariable Long operatorId,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int size) {
        try {
            Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            Page<TicketStatusTrackingDto> operatorHistory = trackingService.getOperatorHistory(operatorId, pageable);
            PageResponse<TicketStatusTrackingDto> pageResponse = PageResponse.of(operatorHistory);
            
            return ResponseEntity.ok(ApiResponse.success("获取操作人记录成功", pageResponse));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取操作人记录失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取时间范围内的跟踪记录
     */
    @GetMapping("/tracking/time-range")
    @Operation(summary = "获取时间范围内的跟踪记录", description = "获取指定时间范围内的所有跟踪记录")
    @RequirePermission(roles = {RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<PageResponse<TicketStatusTrackingDto>>> getTrackingHistoryByTimeRange(
            @Parameter(description = "开始时间") @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant startTime,
            @Parameter(description = "结束时间") @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant endTime,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "20") int size) {
        try {
            Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            Page<TicketStatusTrackingDto> trackingHistory = trackingService.getTrackingHistoryByTimeRange(startTime, endTime, pageable);
            PageResponse<TicketStatusTrackingDto> pageResponse = PageResponse.of(trackingHistory);
            
            return ResponseEntity.ok(ApiResponse.success("获取时间范围跟踪记录成功", pageResponse));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取时间范围跟踪记录失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取工单操作统计
     */
    @GetMapping("/{ticketId}/tracking/stats")
    @Operation(summary = "获取工单操作统计", description = "获取指定工单的操作统计信息")
    @RequirePermission(roles = {RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<List<Object[]>>> getTicketOperationStats(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            List<Object[]> stats = trackingService.getOperationStats(ticketId);
            return ResponseEntity.ok(ApiResponse.success("获取工单操作统计成功", stats));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取工单操作统计失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取操作人统计
     */
    @GetMapping("/tracking/operator/{operatorId}/stats")
    @Operation(summary = "获取操作人统计", description = "获取指定操作人的操作统计信息")
    @RequirePermission(roles = {RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<List<Object[]>>> getOperatorStats(
            @Parameter(description = "操作人ID") @PathVariable Long operatorId) {
        try {
            List<Object[]> stats = trackingService.getOperatorStats(operatorId);
            return ResponseEntity.ok(ApiResponse.success("获取操作人统计成功", stats));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取操作人统计失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取工单操作次数
     */
    @GetMapping("/{ticketId}/tracking/count")
    @Operation(summary = "获取工单操作次数", description = "获取指定工单的总操作次数")
    @RequirePermission(roles = {RoleConstants.CUSTOMER, RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<Long>> getOperationCount(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            Long count = trackingService.getOperationCount(ticketId);
            return ResponseEntity.ok(ApiResponse.success("获取操作次数成功", count));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取操作次数失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取特定类型操作次数
     */
    @GetMapping("/{ticketId}/tracking/count/{trackingType}")
    @Operation(summary = "获取特定类型操作次数", description = "获取指定工单特定类型操作次数")
    @RequirePermission(roles = {RoleConstants.AGENT, RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<Long>> getOperationCountByType(
            @Parameter(description = "工单ID") @PathVariable Long ticketId,
            @Parameter(description = "跟踪类型") @PathVariable TicketStatusTrackingType trackingType) {
        try {
            Long count = trackingService.getOperationCountByType(ticketId, trackingType);
            return ResponseEntity.ok(ApiResponse.success("获取特定类型操作次数成功", count));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("获取特定类型操作次数失败: " + e.getMessage()));
        }
    }
    
    /**
     * 删除工单跟踪记录
     */
    @DeleteMapping("/{ticketId}/tracking")
    @Operation(summary = "删除工单跟踪记录", description = "删除指定工单的所有跟踪记录")
    @RequirePermission(roles = {RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<String>> deleteTicketTracking(
            @Parameter(description = "工单ID") @PathVariable Long ticketId) {
        try {
            trackingService.deleteTicketTracking(ticketId);
            return ResponseEntity.ok(ApiResponse.success("删除工单跟踪记录成功", "已删除工单 " + ticketId + " 的所有跟踪记录"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("删除工单跟踪记录失败: " + e.getMessage()));
        }
    }
    
    /**
     * 清理过期跟踪记录
     */
    @DeleteMapping("/tracking/cleanup")
    @Operation(summary = "清理过期跟踪记录", description = "清理指定时间之前的跟踪记录")
    @RequirePermission(roles = {RoleConstants.ADMIN})
    public ResponseEntity<ApiResponse<Integer>> cleanupExpiredTracking(
            @Parameter(description = "截止时间") @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Instant cutoffTime) {
        try {
            int deletedCount = trackingService.cleanupExpiredTracking(cutoffTime);
            return ResponseEntity.ok(ApiResponse.success("清理过期跟踪记录成功", deletedCount));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error("清理过期跟踪记录失败: " + e.getMessage()));
        }
    }
}

